home *** CD-ROM | disk | FTP | other *** search
Oberon Text | 1995-04-11 | 10.8 KB | 308 lines | [TEXT/.Ob4] |
- Syntax10.Scn.Fnt
- MODULE Kepler9;
- (* Semesterarbeit Wintersemester 91/92 von Samuel Urech
- Erweiterung des Graphikeditors Kepler um Objektklassen f
- r geometrische Zeichnungen.
- Programmiersprache: Oberon-2 auf Ceres-1
- Autor: Samuel Urech, Tannenrauchstrasse 35/107, 8038 Z
- Tel. 01 481 92 92 Stud.Nr. 87-906-434
- Datum: 8.1.92 Stand: 15.1.92 *)
- IMPORT Math, Files, KeplerFrames, KeplerGraphs;
- TYPE
- Parallel* = POINTER TO ParallelDesc;
- ParallelDesc* = RECORD
- ( KeplerGraphs.PlanetDesc )
- END;
- RightAngle* = POINTER TO RightAngleDesc;
- RightAngleDesc* = RECORD
- ( KeplerGraphs.PlanetDesc )
- END;
- Intersection* = POINTER TO IntersectionDesc;
- IntersectionDesc* = RECORD
- ( KeplerGraphs.PlanetDesc )
- END;
- Extension* = POINTER TO ExtensionDesc;
- ExtensionDesc* = RECORD
- ( KeplerGraphs.PlanetDesc )
- END;
- Tangent* = POINTER TO TangentDesc;
- TangentDesc* = RECORD
- ( KeplerGraphs.PlanetDesc )
- sign* : SHORTINT; (* -1 oder 1 f
- r den einen oder anderen Punkt *)
- END;
- CircleInter* = POINTER TO CircleIntersection; (* by jt and ww *)
- CircleIntersection* = RECORD
- (KeplerGraphs.PlanetDesc)
- sign*: SHORTINT
- END;
- CircleLineInter* = POINTER TO CircleLineIntersection; (* by jt and ww *)
- CircleLineIntersection* = RECORD
- (KeplerGraphs.PlanetDesc)
- sign*: SHORTINT
- END;
- (* --------------------------------------- Parallel ---------------------------------------- *)
- PROCEDURE ( self : Parallel ) Calc*;
- BEGIN (* Calc *)
- self.x := self.c.p[ 2 ].x + self.c.p[ 1 ].x - self.c.p[ 0 ].x;
- self.y := self.c.p[ 2 ].y + self.c.p[ 1 ].y - self.c.p[ 0 ].y;
- END Calc;
- PROCEDURE NewParallel*;
- VAR new : Parallel;
- BEGIN (* NewParallel *)
- IF KeplerFrames.nofpts >= 3 THEN
- NEW( new );
- NEW( new.c );
- new.c.nofpts := 3;
- KeplerFrames.ConsumePoint( new.c.p[ 0 ] );
- KeplerFrames.ConsumePoint( new.c.p[ 1 ] );
- KeplerFrames.ConsumePoint( new.c.p[ 2 ] );
- new.Calc;
- KeplerFrames.Focus.Append( new );
- KeplerFrames.Focus.FlipSelection( new );
- END; (* IF *)
- END NewParallel;
- (* --------------------------------------- Right Angle ---------------------------------------- *)
- PROCEDURE ( self : RightAngle ) Calc*;
- VAR x0, y0, x1, y1, x2, y2 : LONGINT;
- f : REAL;
- BEGIN (* Calc *)
- x0 := self.c.p[ 0 ].x;
- y0 := self.c.p[ 0 ].y;
- x1 := self.c.p[ 1 ].x;
- y1 := self.c.p[ 1 ].y;
- x2 := self.c.p[ 2 ].x;
- y2 := self.c.p[ 2 ].y;
- f := ( ( x1 - x0 ) * ( x2 - x0 ) + ( y1 - y0 ) * ( y2 - y0 ) ) / ( ( x1 - x0 ) * ( x1 - x0 ) + ( y1 - y0 ) * ( y1 - y0 ) );
- self.x := SHORT( ENTIER( x0 + ( x1 - x0 ) * f ) );
- self.y := SHORT( ENTIER( y0 + ( y1 - y0 ) * f ) );
- END Calc;
- PROCEDURE NewRightAngle*;
- VAR new : RightAngle;
- BEGIN (* NewRightAngle *)
- IF KeplerFrames.nofpts >= 3 THEN
- NEW( new );
- NEW( new.c );
- new.c.nofpts := 3;
- KeplerFrames.ConsumePoint( new.c.p[ 0 ] );
- KeplerFrames.ConsumePoint( new.c.p[ 1 ] );
- KeplerFrames.ConsumePoint( new.c.p[ 2 ] );
- new.Calc;
- KeplerFrames.Focus.Append( new );
- KeplerFrames.Focus.FlipSelection( new );
- END; (* IF *)
- END NewRightAngle;
- (* --------------------------------------- Line * Line Intersection ---------------------------------------- *)
- PROCEDURE ( self : Intersection ) Calc*;
- VAR f, x0, y0, x1, y1, x2, y2, x3, y3 : LONGINT;
- BEGIN (* Calc *)
- x0 := self.c.p[ 0 ].x;
- y0 := self.c.p[ 0 ].y;
- x1 := self.c.p[ 1 ].x;
- y1 := self.c.p[ 1 ].y;
- x2 := self.c.p[ 2 ].x;
- y2 := self.c.p[ 2 ].y;
- x3 := self.c.p[ 3 ].x;
- y3 := self.c.p[ 3 ].y;
- f := ( x3 - x2 ) * ( y1 - y0 ) - ( x1 - x0 ) * ( y3 - y2 );
- IF f # 0 THEN (* sonst alte Werte beibehalten *)
- self.x := SHORT( ( ( x3 - x2 ) * ( x1 - x0 ) * ( y2 - y0 ) + ( x3 - x2 ) * ( y1 - y0 ) * x0 - ( x1 - x0 ) * ( y3 - y2 ) * x2 ) DIV f );
- self.y := SHORT( ( ( y3 - y2 ) * ( y1 - y0 ) * ( x2 - x0 ) + ( y3 - y2 ) * ( x1 - x0 ) * y0 - ( y1 - y0 ) * ( x3 - x2 ) * y2 ) DIV ( - f ) );
- END; (* IF *)
- END Calc;
- PROCEDURE NewLineIntersection*;
- VAR new : Intersection;
- BEGIN (* NewIntersection *)
- IF KeplerFrames.nofpts >= 4 THEN
- NEW( new );
- NEW( new.c );
- new.c.nofpts := 4;
- KeplerFrames.ConsumePoint( new.c.p[ 0 ] );
- KeplerFrames.ConsumePoint( new.c.p[ 1 ] );
- KeplerFrames.ConsumePoint( new.c.p[ 2 ] );
- KeplerFrames.ConsumePoint( new.c.p[ 3 ] );
- new.Calc;
- KeplerFrames.Focus.Append( new );
- KeplerFrames.Focus.FlipSelection( new );
- END; (* IF *)
- END NewLineIntersection;
- (* --------------------------------------- Circle * Circle Intersection ---------------------------------------- *)
- PROCEDURE (self : CircleInter) Calc*;
- VAR M1x, M2x, M1y, M2y, R1x, R2x, R1y, R2y,
- mx, my, d, c, s, r1, r2, qx, qy, h: REAL;
- BEGIN
- M1x := self.c.p[0].x; M2x := self.c.p[2].x;
- M1y := self.c.p[0].y; M2y := self.c.p[2].y;
- R1x := self.c.p[1].x; R2x := self.c.p[3].x;
- R1y := self.c.p[1].y; R2y := self.c.p[3].y;
- mx := M2x - M1x; my := M2y - M1y; d := Math.sqrt(mx * mx + my * my);
- IF d # 0 THEN
- c := my / d; s := -mx / d;
- r1 := (M1x - R1x) * (M1x - R1x) + (M1y - R1y) * (M1y - R1y);
- r2 := (M2x - R2x) * (M2x - R2x) + (M2y - R2y) * (M2y - R2y);
- qy := (d + (r1 - r2) / d) / 2;
- h := r1 - qy * qy;
- IF h >= 0 THEN
- qx := self.sign * Math.sqrt(h);
- self.x := SHORT(ENTIER(c * qx - s * qy + M1x));
- self.y := SHORT(ENTIER(s * qx + c * qy + M1y))
- END
- END
- END Calc;
- PROCEDURE (self : CircleInter) Read*(VAR r : Files.Rider);
- BEGIN
- Files.Read(r, self.sign);
- self.Read^(r);
- END Read;
- PROCEDURE (self : CircleInter) Write*(VAR r : Files.Rider);
- BEGIN
- Files.Write(r, self.sign);
- self.Write^(r);
- END Write;
- PROCEDURE NewCircleIntersection*;
- VAR new1, new2 : CircleInter;
- BEGIN
- IF KeplerFrames.nofpts >= 4 THEN
- NEW(new1); new1.sign := 1; NEW(new1.c ); new1.c.nofpts := 4;
- NEW(new2); new2.sign := -1; NEW(new2.c ); new2.c.nofpts := 4;
- KeplerFrames.ConsumePoint(new1.c.p[0]); (* middle 1 *)
- KeplerFrames.ConsumePoint(new1.c.p[1]); (* periphery 1 *)
- KeplerFrames.ConsumePoint(new1.c.p[2]); (* middle 2 *)
- KeplerFrames.ConsumePoint(new1.c.p[3]); (* periphery 2 *)
- new2.c.p[0] := new1.c.p[0]; INC(new1.c.p[0].refcnt);
- new2.c.p[1] := new1.c.p[1]; INC(new1.c.p[1].refcnt);
- new2.c.p[2] := new1.c.p[2]; INC(new1.c.p[2].refcnt);
- new2.c.p[3] := new1.c.p[3]; INC(new1.c.p[3].refcnt);
- new1.Calc; new2.Calc;
- KeplerFrames.Focus.Append(new1); KeplerFrames.Focus.Append(new2);
- KeplerFrames.Focus.FlipSelection(new1); KeplerFrames.Focus.FlipSelection(new2)
- END
- END NewCircleIntersection;
- (* --------------------------------------- Circle * Line Intersection ---------------------------------------- *)
- PROCEDURE (self : CircleLineInter) Calc*;
- VAR M1x, L1x, M1y, L1y, R1x, L2x, R1y, L2y, M2x, M2y,
- mx, my, d, c, s, r1, qy, h: REAL;
- BEGIN
- M1x := self.c.p[0].x; L1x := self.c.p[2].x;
- M1y := self.c.p[0].y; L1y := self.c.p[2].y;
- R1x := self.c.p[1].x; L2x := self.c.p[3].x;
- R1y := self.c.p[1].y; L2y := self.c.p[3].y;
- mx := L2x - L1x; my := L2y - L1y; d := Math.sqrt(mx * mx + my * my);
- IF d # 0 THEN
- c := my / d; s := -mx / d;
- r1 := (M1x - R1x) * (M1x - R1x) + (M1y - R1y) * (M1y - R1y);
- M1x := M1x - L2x; M1y := M1y - L2y;
- M2x := c * M1x + s * M1y; M2y := c * M1y - s * M1x;
- h := r1 - M2x * M2x;
- IF h >= 0 THEN
- qy := self.sign * Math.sqrt(h) + M2y;
- self.x := SHORT(ENTIER(-s * qy + L2x));
- self.y := SHORT(ENTIER(c * qy + L2y))
- END
- END
- END Calc;
- PROCEDURE (self : CircleLineInter) Read*(VAR r : Files.Rider);
- BEGIN
- Files.Read(r, self.sign);
- self.Read^(r);
- END Read;
- PROCEDURE (self : CircleLineInter) Write*(VAR r : Files.Rider);
- BEGIN
- Files.Write(r, self.sign);
- self.Write^(r);
- END Write;
- PROCEDURE NewCircleLineIntersect*;
- VAR new1, new2 : CircleLineInter;
- BEGIN
- IF KeplerFrames.nofpts >= 4 THEN
- NEW(new1); new1.sign := 1; NEW(new1.c ); new1.c.nofpts := 4;
- NEW(new2); new2.sign := -1; NEW(new2.c ); new2.c.nofpts := 4;
- KeplerFrames.ConsumePoint(new1.c.p[0]); (* middle 1 *)
- KeplerFrames.ConsumePoint(new1.c.p[1]); (* periphery 1 *)
- KeplerFrames.ConsumePoint(new1.c.p[2]); (* line start *)
- KeplerFrames.ConsumePoint(new1.c.p[3]); (* line end *)
- new2.c.p[0] := new1.c.p[0]; INC(new1.c.p[0].refcnt);
- new2.c.p[1] := new1.c.p[1]; INC(new1.c.p[1].refcnt);
- new2.c.p[2] := new1.c.p[2]; INC(new1.c.p[2].refcnt);
- new2.c.p[3] := new1.c.p[3]; INC(new1.c.p[3].refcnt);
- new1.Calc; new2.Calc;
- KeplerFrames.Focus.Append(new1); KeplerFrames.Focus.Append(new2);
- KeplerFrames.Focus.FlipSelection(new1); KeplerFrames.Focus.FlipSelection(new2)
- END
- END NewCircleLineIntersect;
- (* --------------------------------------- Extension ---------------------------------------- *)
- PROCEDURE ( self : Extension ) Calc*;
- BEGIN (* Calc *)
- self.x := 2 * self.c.p[ 1 ].x - self.c.p[ 0 ].x;
- self.y := 2 * self.c.p[ 1 ].y - self.c.p[ 0 ].y;
- END Calc;
- PROCEDURE NewExtension*;
- VAR new : Extension;
- BEGIN (* NewExtension *)
- IF KeplerFrames.nofpts >= 2 THEN
- NEW( new );
- NEW( new.c );
- new.c.nofpts := 2;
- KeplerFrames.ConsumePoint( new.c.p[ 0 ] );
- KeplerFrames.ConsumePoint( new.c.p[ 1 ] );
- new.Calc;
- KeplerFrames.Focus.Append( new );
- KeplerFrames.Focus.FlipSelection( new );
- END; (* IF *)
- END NewExtension;
- (* --------------------------------------- Tangent ---------------------------------------- *)
- PROCEDURE ( self : Tangent ) Calc*;
- VAR x0, x1, x2, y0, y1, y2 : LONGINT;
- r2, d2, x3, y3, faktor : REAL;
- BEGIN (* Calc *)
- x0 := self.c.p[ 0 ].x;
- x1 := self.c.p[ 1 ].x;
- x2 := self.c.p[ 2 ].x;
- y0 := self.c.p[ 0 ].y;
- y1 := self.c.p[ 1 ].y;
- y2 := self.c.p[ 2 ].y;
- r2 := ( x1 - x0 ) * ( x1 - x0 ) + ( y1 - y0 ) * ( y1 - y0 );
- d2 := ( x2 - x0 ) * ( x2 - x0 ) + ( y2 - y0 ) * ( y2 - y0 );
- IF r2 < d2 THEN (* Punkt liegt ausserhalb des Kreises *)
- x3 := x0 + ( x2 - x0 ) * r2 / d2;
- y3 := y0 + ( y2 - y0 ) * r2 / d2;
- faktor := Math.sqrt( r2 / d2 - r2 * r2 / d2 / d2 );
- self.x := SHORT( ENTIER( x3 + self.sign * faktor * ( y2 - y0 ) ) );
- self.y := SHORT( ENTIER( y3 + self.sign * faktor * ( x0 - x2 ) ) );
- END; (* IF *)
- END Calc;
- PROCEDURE ( self : Tangent ) Read*( VAR r : Files.Rider );
- BEGIN
- Files.Read( r, self.sign );
- self.Read^( r );
- END Read;
- PROCEDURE ( self : Tangent ) Write*( VAR r : Files.Rider );
- BEGIN
- Files.Write( r, self.sign );
- self.Write^( r );
- END Write;
- PROCEDURE NewTangent*;
- VAR new : Tangent;
- p0, p1, p2 : KeplerGraphs.Star;
- i : SHORTINT;
- BEGIN
- IF KeplerFrames.nofpts >= 3 THEN
- KeplerFrames.ConsumePoint( p0 ); INC( p0.refcnt );
- KeplerFrames.ConsumePoint( p1 ); INC( p1.refcnt );
- KeplerFrames.ConsumePoint( p2 ); INC( p2.refcnt );
- FOR i := 0 TO 1 DO
- NEW( new );
- new.sign := 2 * i - 1;
- NEW( new.c );
- new.c.nofpts := 3;
- new.c.p[ 0 ] := p0;
- new.c.p[ 1 ] := p1;
- new.c.p[ 2 ] := p2;
- new.Calc;
- KeplerFrames.Focus.Append( new );
- KeplerFrames.Focus.FlipSelection( new );
- END
- END
- END NewTangent;
- END Kepler9.
-